package com.dragon.pagingsample;

import android.util.SparseArray;

/**
 * 对象池
 *
 *  使用SparseArray数组  对于数据量比较少的情况
 */
public abstract class ObjectPool<T> {
    private SparseArray<T> freePool;  //能用的
    private SparseArray<T> lentPool;  //正在用的池

    //池子最大值
    private int maxCapacity;

    public ObjectPool(int initialCapacity,int maxCapacity){
        initalize(initialCapacity);
        this.maxCapacity = maxCapacity;
    }

    private void initalize(int initialCapacity) {
        lentPool = new SparseArray<>();
        freePool = new SparseArray<>();

        for (int i = 0; i < initialCapacity; i++) {
            freePool.put(i,create());
        }
    }

    /**
     * 申请对象
     * @return T
     */
    public T acquire(){
        T t = null;
        synchronized (freePool){
            int freeSize = freePool.size();
            for (int i = 0; i < freeSize; i++) {
                int key = freePool.keyAt(i);
                t = freePool.get(key);
                if (null != t){
                    this.lentPool.put(key,t);
                    this.freePool.remove(key);
                    return t;
                }
            }

            //如果没对象可用
            if (t==null && lentPool.size()+freeSize < maxCapacity){
                t = create();
                lentPool.put(lentPool.size()+freeSize,t);
            }
        }
        return t;
    }

    /**
     * 回收对象
     * @param t
     */
    public void release(T t){
        if (t == null){
            return;
        }
        int key = lentPool.indexOfValue(t);
        //释放前把这个对象交给用户处理
        restore(t);

        this.freePool.put(key,t);
        lentPool.remove(key);
    }

    protected  void restore(T t){

    }

    protected abstract T create() ;

    public ObjectPool(int maxCapacity){
        this(maxCapacity/2,maxCapacity);
    }
}
